﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI;
using Controls.CollapseExpandTreeView;
using System.Reflection;

[assembly: WebResource(CollapseExpandTreeView.JS_URL, "text/javascript", PerformSubstitution = true)]

namespace Controls.CollapseExpandTreeView
{
    public class CollapseExpandTreeView : TreeView
    {
        #region Private Properties
        private HtmlInputButton Expand { get; set; }
        private HtmlInputButton Collapse { get; set; }
        #endregion

        #region Const
        private const string CSS_CLASS_EXPAND = "CssClassExpand";
        private const string CSS_CLASS_COLLAPSE = "CssClassCollapse";
        private const string EXPAND_TEXT = "ExpandText";
        private const string COLLAPSE_TEXT = "CollapseText";
        internal const string JS_URL = "Controls.CollapseExpandTreeView.ExpandCollapse.js";
        #endregion

        #region Ctor
        public CollapseExpandTreeView()
        {
            Expand = new HtmlInputButton();
            Collapse = new HtmlInputButton();

            ExpandText = "Expand All";
            CollapseText = "Collapse All";
        }
        #endregion

        #region Method

        /// <summary>
        /// Return string value from ViewState
        /// </summary>
        /// <param name="key">The key in The ViewState</param>
        /// <returns></returns>
        private string GetFromViewState(string key)
        {
            string s = (string)ViewState[key];
            return ((s == null) ? String.Empty : s);
        }

        /// <summary>
        /// Return string value of property that locate in the base type and it is not public
        /// </summary>
        /// <param name="propName">The property name</param>
        /// <returns></returns>
        private string GetValueFromReflaction(string propName)
        {
            Type type = GetType().BaseType;
            PropertyInfo pi = type.GetProperty(propName, BindingFlags.Instance | BindingFlags.NonPublic);
            object value = pi.GetValue(this, null);
            return value.ToString();
        }

        /// <summary>
        /// Gets the Expand Image Url
        /// </summary>
        private string ExpandImageUrlInternal
        {
            get
            {
                string url = GetValueFromReflaction("ExpandImageUrlInternal");
                if (url == "")
                {
                    // The default expand image url
                    url = "/WebResource.axd?d=wheI3Jge_pneveLkEraSoYxlmKNnqYa0X1_njXGO0bg1&t=633744831123074071";
                }

                return url;
            }
        }

        /// <summary>
        /// Gets the Collapse Image Url
        /// </summary>
        private string CollapseImageUrlInternal
        {
            get
            {
                string url = GetValueFromReflaction("CollapseImageUrlInternal");
                if (url == "")
                {
                    // The default collapse image url
                    url = "/WebResource.axd?d=wheI3Jge_pneveLkEraSoeJ2AkLjYF7aizzZ7NzLi441&t=633744831123074071";
                }
                return url;
            }
        }

        #endregion

        #region Public Properties
        [Category("Collapse Expand")]
        [Description("Css Class for the expand button")]
        public string CssClassExpand
        {
            get
            {
                return GetFromViewState(CSS_CLASS_EXPAND);
            }
            set
            {
                ViewState[CSS_CLASS_EXPAND] = value;
            }
        }

        [Category("Collapse Expand")]
        [Description("Css Class for the collapse button")]
        public string CssClassCollapse
        {
            get
            {
                return GetFromViewState(CSS_CLASS_COLLAPSE);
            }
            set
            {
                ViewState[CSS_CLASS_COLLAPSE] = value;
            }
        }

        [Category("Collapse Expand")]
        [Description("Text for the expand button")]
        [DefaultValue("Expand All")]
        public string ExpandText
        {
            get
            {
                return GetFromViewState(EXPAND_TEXT);
            }
            set
            {
                ViewState[EXPAND_TEXT] = value;
            }
        }

        [Category("Collapse Expand")]
        [Description("Text for the collapse button")]
        [DefaultValue("Collapse All")]
        public string CollapseText
        {
            get
            {
                return GetFromViewState(COLLAPSE_TEXT);
            }
            set
            {
                ViewState[COLLAPSE_TEXT] = value;
            }
        }
        #endregion

        #region Override

        protected override void Render(HtmlTextWriter writer)
        {
            // Add the data for the collapse button
            Collapse.Attributes["class"] = CssClassCollapse;
            Collapse.Value = CollapseText;
            // Register the onclick evenr to the ChnageTreeViewStatus function
            Collapse.Attributes["onclick"] = string.Format("ChnageTreeViewStatus('{0}', '{1}')", ClientID, CollapseImageUrlInternal);

            // Add the data for the expand button
            Expand.Attributes["class"] = CssClassExpand;
            Expand.Value = ExpandText;
            // Register the onclick evenr to the ChnageTreeViewStatus function
            Expand.Attributes["onclick"] = string.Format("ChnageTreeViewStatus('{0}', '{1}')", ClientID, ExpandImageUrlInternal);

            // Start rendering the tree
            // we render a table with two rows, in the first row we render two cells, in each cell we render one button,
            // and in other row we render a cell with the tree.
            writer.RenderBeginTag(HtmlTextWriterTag.Table);
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            Expand.RenderControl(writer);
            writer.RenderEndTag();  //HtmlTextWriterTag.Td
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            Collapse.RenderControl(writer);
            writer.RenderEndTag();  //HtmlTextWriterTag.Td
            writer.RenderEndTag();  //HtmlTextWriterTag.Tr
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            base.Render(writer);
            writer.RenderEndTag();  //HtmlTextWriterTag.Td
            writer.RenderEndTag();  //HtmlTextWriterTag.Tr
            writer.RenderEndTag();  //HtmlTextWriterTag.Table
        }

        protected override void OnPreRender(EventArgs e)
        {
            // Register the ExpandCollpase.js in the page
            Page.ClientScript.RegisterClientScriptResource(GetType(), JS_URL);

            base.OnPreRender(e);
        }
        #endregion
    }
}
